# PollMonster - a distributed data collection framework
# Copyright (C) 2010 Jerry Lundström
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PollMonster is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PollMonster.  If not, see <http://www.gnu.org/licenses/>.

=head1 NAME

PollMonster - The great new PollMonster!

=head1 VERSION

See L<PollMonster> for version.

=cut

=head1 SYNOPSIS

Quick summary of what the module does.

Perhaps a little code snippet.

    use PollMonster;

    my $foo = PollMonster->new();
    ...

=head1 EXPORT

A list of functions that can be exported.  You can delete this section
if you don't export anything, such as for a purely object-oriented module.

=head1 SUBROUTINES/METHODS

=head2 function1

=cut

package ProcessorExample;

use common::sense;

use PollMonster::ModuleFactory;

use AnyEvent ();

use Time::HiRes ();

PollMonster::ModuleFactory->instance->register_processor(
    'example',
    { verify_order => sub {
        my ($parameter) = @_;

        my %parameter = (
            elements => 0,
            benchmark => 1,
            interval => 1,
            callback => 0,
            %$parameter
            );

        return \%parameter;
      },
      run => sub {
          my ($processor, $uuid, $parameter) = @_;

          if ($parameter->{benchmark}) {
              my ($in_count, $in_last, $out_count, $out_last, $time);

              if (%{$processor->state}) {
                  $out_count = $processor->state->{out_count};
                  $in_count = $processor->state->{in_count};
              }

              $time = Time::HiRes::time;
              my $timer = AnyEvent->timer(
                  after => 1, interval => 1,
                  cb => sub {
                      my ($in, $out, $slept);

                      $slept = Time::HiRes::time() - $time;

                      $in = $in_count - $in_last;
                      $out = $out_count - $out_last;
                      $in_last += $in;
                      $out_last += $out;

                      if ($slept < 1.0) {
                          $in += $in * (1.0 - $slept);
                      }
                      elsif ($slept > 1.0) {
                          $in /= $slept;
                      }

                      $processor->warn('in rate: ', $in, '/s  out rate: ', $out, '/s');

                      $time = Time::HiRes::time();
                  });

              while (!$processor->end) {
                  my $work = PollMonster::ModuleFactory->instance->call_worker('example', 'new');
                  if ($parameter->{elements} > 0) {
                      $work->set_num_elements($parameter->{elements});
                  }
                  if ($processor->work($work)) {
                      $out_count++;
                  }
                  else {
                      $processor->sleep(0.01);
                  }

                  while(defined (my $result = $processor->result)) {
                      $in_count++;
                  }
              }

              $processor->state->{out_count} = $out_count;
              $processor->state->{in_count} = $in_count;
          }
          else {
              while (!$processor->end) {
                  while($processor->result) { }

                  my $work = PollMonster::ModuleFactory->instance->call_worker('example', 'new');
                  if ($parameter->{elements} > 0) {
                      $work->set_num_elements($parameter->{elements});
                  }
                  $processor->work($work);
                  my $result = $processor->result_wait_timeout(10);
                  if (defined $result) {
                      $processor->info('example work took ', ($result->received - $result->sent),
                                       ' seconds to sent and ', (Time::HiRes::time - $result->received),
                                       ' to receive');
                      if ($parameter->{callback}) {
                          $processor->callback_result({sent => ($result->received - $result->sent),
                                                       receive => (Time::HiRes::time - $result->received)},
                                                      1);
                          $processor->stop;
                          next;
                      }
                  }
                  else {
                      $processor->warn('timeout running example work');
                  }

                  $processor->sleep($parameter->{interval});
                  $processor->ran;
              }
          }
      }
    });

=head1 AUTHOR

Jerry Lundström, C<< <lundstrom.jerry at gmail.com> >>

=head1 BUGS

Please report any bugs or feature requests to C<bug-pollmonster at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=PollMonster>.  I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.




=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc PollMonster


You can also look for information at:

=over 4

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=PollMonster>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/PollMonster>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/PollMonster>

=item * Search CPAN

L<http://search.cpan.org/dist/PollMonster/>

=back


=head1 ACKNOWLEDGEMENTS


=head1 LICENSE AND COPYRIGHT

Copyright 2010 Jerry Lundström.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

PollMonster is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with PollMonster.  If not, see <http://www.gnu.org/licenses/>.


=cut

1;
